<?php
/**
 * Created on 22.12.2005
 * 
 * <ajax:form name="hans2" action="seb::form2" update="anzeige" error="error">
 * 
 * to handle an ajax form you need two action methods, one for calling the
 * handleAjaxUpdate method of WebAction and a second, which is called by
 * handleAjaxUpdate, if no errors occurred while validation.
 * 
 * e.g.
 * 
 * $this->handlAjaxUpdate("my/test", "form", "my::test", "MyAction", "_doSomething");
 * 
 * first argument:  path to psp with form (alike method validate)
 * second argument: name of the form to validate
 * third argument:  incoming action which displayed the form
 * fourth argument: action class name of action with action method to call if successful
 * fifth argument:  action method to call if successful
 * 
 * update or update, error, load or error, load
 * 
 * update => id of element to update
 * load, error => name of callback functions
 * handle => callback function which handles all types of events after submit
 * jsresponse => used instead of handle; works the same way, except, that the responded
 *              psp contains a js function, which is called, if validation was correct;
 *              use ajax:response as root tag of the page 
 * onsubmit => js code is evaluated before "submit"
 * onhandle => JS CODE which is evaluated after "handle"; ATTENTION: only with 
 *              update, else you have to use handle, but without load and error
 * 
 * if 'update' and 'jsresponse' are not used, the form is NOT updated (validationErrorStyle)
 */

// TODO add target attribute, if validate name is required
class ajax_formHandler
{
    
    var $name = null;
    var $attributes = array(
        'type',
        'action',
        'value',
        'name',
        'module',
        'update',
        'handle',
        'load',
        'error',
        'onsubmit',
        'onhandle',
        'jsresponse',
        'validate',
        'validationParam',
        'pspc'
    );

    function startElement (& $sender, $attrs, $line)
    {
        $attrs['type'] = 'form';
        $sender->pushParent($attrs);
        $run = &phpinchains_RuntimeConfig::getInstance();
        $actionParam   = $run->get("actionParam");
        $actionParamId = $run->get("actionParamId");
        $moduleParam   = $run->get("moduleParam");
        $moduleParamId = $run->get("moduleParamId");
        if (!$attrs['value'] && !$attrs['action'])
        {
            die ("Attribute value or action is missing in form tag in line $line!\n");
        }
        if (!$attrs['name'])
        {
            die ("Attribute name is missing in form tag in line $line!\n");
        }
        $url = '';
        if ($attrs['value'])
            $url = $attrs['value'];
        else
        {
            if ($actionParam == 'pathInfo')
            {
                if ($attrs['module'])
                    $url = '$env->getServer("SCRIPT_NAME")."/".'.$attrs['module'].'."/".'.$attrs['action'];
                elseif ($moduleParam)
                    $url = '$env->getServer("SCRIPT_NAME")."/'.$moduleParam.'/".'.$attrs['action'];
                else
                    $url = '$env->getServer("SCRIPT_NAME")."/".'.$attrs['action'];
            }
            elseif ($actionParam == 'queryString')
            {
                if ($attrs['module'])
                    $mod = $attrs['module'];            
                elseif ($moduleParam)
                    $mod = '"'.$moduleParam.'"';
                $url = '$env->getServer("SCRIPT_NAME")."?'.$moduleParamId.'=".'.$mod.'."&'.$actionParamId.'=".'.$attrs['action'];
            }
        }
        if ($attrs['update'])
        {
            $fnname = 'phpinchains.func.__'.str_replace("'","", $attrs['name']).'ajaxupdate';
            $js = '    '.$fnname.' = function (type, data, evt) {      
        var obj = eval("("+evt.responseText+")");
        var callback;
        if (type == "load") {
            dojo.byId('.$attrs['update'].').innerHTML = obj.result;
            dojo.byId("__"+'.$attrs['name'].'+"form").innerHTML = obj.form;'."\n";
            if ($attrs['load'])
                $js .= '            callback = '.str_replace("'", "", $attrs['load']).'; callback(type, data, evt);'."\n";
            $js .= '        } else { 
            dojo.byId("__"+'.$attrs['name'].'+"form").innerHTML = obj.form;'."\n";
            if ($attrs['error'])
                $js .= '            callback = '.str_replace("'", "", $attrs['error']).'; callback(type, data, evt);'."\n";
            $js .= '        }
    };
';
            $sender->appendJSCode($js);
            if ($attrs['onhandle'])
                $attrs['handle'] = "'function (type, data, evt) {'.".$attrs['onhandle'].".';$fnname(type, data, evt);}'";
            elseif ($attrs['handle'])
                $attrs['handle'] = "'function (type, data, evt) {'.".$attrs['handle'].".';$fnname(type, data, evt);}'";
            else
                $attrs['handle'] = "'$fnname'";
        }
        elseif ($attrs['jsresponse'] == "'true'")
        {
            $fnname = 'phpinchains.func.__'.str_replace("'","", $attrs['name']).'ajaxupdate';
            $js = '    '.$fnname.' = function (type, data, evt) {      
        var obj = eval("("+evt.responseText+")");
        var callback;
        type = "load";
        if (type == "load") {
            var resfunobj = eval(\'({ "fun": \' + obj.result + "})");
            resfunobj.fun();
            dojo.byId("__"+'.$attrs['name'].'+"form").innerHTML = obj.form;dojo.hostenv.makeWidgets();phpinchains.onAfterUpdate();'."\n";
            if ($attrs['load'])
                $js .= '            callback = '.str_replace("'", "", $attrs['load']).'; callback(type, data, evt);'."\n";
            $js .= '        } else { 
            dojo.byId("__"+'.$attrs['name'].'+"form").innerHTML = obj.form;dojo.hostenv.makeWidgets();phpinchains.onAfterUpdate();'."\n";
            if ($attrs['error'])
                $js .= '            callback = '.str_replace("'", "", $attrs['error']).'; callback(type, data, evt);'."\n";
            $js .= '        }
    };
';
            $sender->appendJSCode($js);
            if ($attrs['onhandle'])
                $attrs['handle'] = "'function (type, data, evt) {'.".$attrs['onhandle'].".';$fnname(type, data, evt);}'";
            elseif ($attrs['handle'])
                $attrs['handle'] = "'function (type, data, evt) {'.".$attrs['handle'].".';$fnname(type, data, evt);}'";
            else
                $attrs['handle'] = "'$fnname'";
        }
        $js = '$out->write(\'dojo.io.bind({\');';
        if ($attrs['load'] && !$attrs['update'] && $attrs['jsresponse'] != "'true'")
            $js .= '$out->write(\' load: \'.'.$attrs['load'].'.",");';
        if ($attrs['error'] && !$attrs['update'] && $attrs['jsresponse'] != "'true'")
            $js .= '$out->write(\' error: \'.'.$attrs['error'].'.",");';
        if ($attrs['handle'])
            $js .= '$out->write(\' load: \'.'.$attrs['handle'].'.",");';
        $js .= '$out->write(\' formNode: this });\');';
        $tag = '$out->write("<form';
        // not supported by dojo
        if ($url)
        {
            $tag .= ' action=\\"".'.$url.'."\\"';
        }
        if ($attrs['enctype'])
        {
            $tag .= ' enctype=\\"".'.$attrs['enctype'].'."\\"';
        }
        if ($attrs['name'])
        {
            $tag .= ' name=\\"".'.$attrs['name'].'."\\" id=\\"__".'.$attrs['name'].'."form\\"';
        }
        $submitjs = '';
        if ($attrs['onsubmit'])
            $submitjs = '$out->write('.$attrs['onsubmit'].'.";");';
        $tag .= ' method=\\"POST\\" onsubmit=\\"");'.$submitjs.'$out->write("try{");'
            .$js
            .'$out->write("}catch(e){};return false;\\"';
        foreach ($attrs as $n => $v)
        {
            if (!in_array($n, $this->attributes))
            {
                $tag .= ' '.$n.'=\"".'.$v.'."\"';
            }
        }
        $tag .= '>");'."\n";
        if ($attrs['jsresponse'] == "'true'") {
        	$tag .= '$out->write("<input type=\\"hidden\\" name=\\"jsresponse\\" value=\\"true\\"/>");';
        }
        if ($lastView = $env->getAttribute('__lastView'))
        {
            $tag .= '$out->write("<input type=\\"hidden\\" name=\\"__lastView\\" value=\\"'.$lastView.'\\"/>");';
        }
        if ($attrs['name']) 
        {
            $tag .= '$out->write("<input type=\\"hidden\\" name=\\"__formName\\" value=\\"".'.$attrs['name'].'."\\"/>");';
        }
       	$tag .= "\$run = &phpinchains_RuntimeConfig::getInstance();\n";
       	$tag .= "if (\$run->get('sec_code_enabled')) {\n";
        $tag .= '    $out->write("<input type=\\"hidden\\" name=\\"__ss\\" value=\\"".$env->getSession(\'phpinchains_sec_code\')."\\"/>");';
       	$tag .= "}\n";
       	$tag .= "if (is_array(\$run->get('additional_parameters'))) {\n";
       	$tag .= '    $'."__params = \$run->get('additional_parameters');\n";
       	$tag .= "    foreach (\$__params as \$n => \$v) {\n";
        $tag .= '        $out->write("<input type=\\"hidden\\" name=\\"$n\\" value=\\"$v\\"/>");';
       	$tag .= "    }\n";
       	$tag .= "}\n";
       	$sender->appendCode($tag);
        $sender->beginCaptureForm(substr($attrs['name'], 1, -1));
        // validation code
        if ($attrs['name'])
        {
            $code  = "      if (\$formname == ".$attrs['name'].")\n        {\n";
            if ($attrs['validate'])
                $code .= "\n        \$this->validateField(\$env, \$actionform, ".$attrs['name'].", ".(isset($attrs['validationParam'])?$attrs['validationParam']:"''").', '.$attrs['validate'].");\n";
            $this->name = $attrs['name'];
            $sender->appendValidationCode($code);
        }
    }

    function endElement (& $sender)
    {
        $sender->popParent();
        $sender->endCaptureForm();
        $sender->appendCode('$out->write("</form>");'."\n");
        // validation code
        if ($this->name != null)
        {
            $code = "\n     \$returnVal = (\$returnVal && !\$validationErrors->hasErrors());\n      }\n";
            $sender->appendValidationCode($code);
            $this->name = null;
        }
    }

}

?>